package com.aggeek.springbootlearning;

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.util.Iterator;
import java.util.Map;

/**
 * author:liuao
 * description:封装的http调用
 * Date: create on 11:48 2017/12/18
 * modify by:
 */
public class MyHttpClient {

    private static MyHttpClient myHttpClient = new MyHttpClient();

    private HttpClient httpClient=null;

    private String charset ="UTF-8";

    private int timeOut = 10000;

    private boolean useProxy = false;

    private String proxyHost = null;

    private int proxyPort = 80;

    private String proxyUsername = null;

    private String proxyPassword = null;

    private boolean initialized = false;

    public static MyHttpClient getInstance() {
        return myHttpClient;
    }

    private  MyHttpClient()  {
        httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
        httpClient.getParams().setParameter("http.protocol.content-charset", "UTF-8");
        httpClient.getParams().setContentCharset("UTF-8");
        httpClient.getParams().setSoTimeout(timeOut);
    }

    public MyHttpClient(String charset, int timeout, boolean useProxy,
                       String proxyHost, int proxyPort, String proxyUsername,
                       String proxyPassword) {
        httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
        if(charset != null && !"".equals(charset.trim())) {
            this.charset = charset;
        }
        if(timeout > 0) {
            this.timeOut = timeout;
        }
        httpClient.getParams().setParameter("http.protocol.content-charset", charset);
        httpClient.getParams().setContentCharset(charset);
        httpClient.getParams().setSoTimeout(timeout);
        if(useProxy && proxyHost != null &&
                !"".equals(proxyHost.trim()) && proxyPort > 0) {
            HostConfiguration hc = new HostConfiguration();
            hc.setProxy(proxyHost, proxyPort);
            httpClient.setHostConfiguration(hc);
            if (proxyUsername != null && !proxyUsername.trim().equals("") &&
                    proxyPassword != null && !proxyPassword.trim().equals("")) {
                httpClient.getState().setProxyCredentials(AuthScope.ANY,
                        new UsernamePasswordCredentials(proxyUsername, proxyPassword));
            }
        }
        initialized = true;
    }

    public synchronized void init() {
        if(charset != null && !"".equals(charset.trim())) {
            httpClient.getParams().setParameter("http.protocol.content-charset", charset);
            httpClient.getParams().setContentCharset(charset);
        }
        if(timeOut > 0) {
            httpClient.getParams().setSoTimeout(timeOut);
        }
        if(useProxy && proxyHost != null &&
                !"".equals(proxyHost.trim()) && proxyPort > 0) {
            HostConfiguration hc = new HostConfiguration();
            hc.setProxy(proxyHost, proxyPort);
            httpClient.setHostConfiguration(hc);
            if (proxyUsername != null && !proxyUsername.trim().equals("") &&
                    proxyPassword != null && !proxyPassword.trim().equals("")) {
                httpClient.getState().setProxyCredentials(AuthScope.ANY,
                        new UsernamePasswordCredentials(proxyUsername, proxyPassword));
            }
        }
        initialized = true;
    }
    public String invoke(String url, Map params, boolean isPost) throws Exception {
        HttpMethod httpMethod = null;
        String result = "";
        try {
            if(isPost && params != null && params.size() > 0) {
                Iterator paramKeys = params.keySet().iterator();
                httpMethod = new PostMethod(url);
                NameValuePair[] form = new NameValuePair[params.size()];
                int formIndex = 0;
                while(paramKeys.hasNext()) {
                    String key = (String)paramKeys.next();
                    Object value = params.get(key);
                    if(value != null && value instanceof String && !value.equals("")) {
                        form[formIndex] = new NameValuePair(key, (String)value);
                        formIndex++;
                    } else if(value != null && value instanceof String[] &&
                            ((String[])value).length > 0) {
                        NameValuePair[] tempForm =
                                new NameValuePair[form.length + ((String[])value).length - 1];
                        for(int i=0; i<formIndex; i++) {
                            tempForm[i] = form[i];
                        }
                        form = tempForm;
                        for(String v : (String[])value) {
                            form[formIndex] = new NameValuePair(key, (String)v);
                            formIndex++;
                        }
                    }
                }
                ((PostMethod)httpMethod).setRequestBody(form);
            } else {
                if(params != null && params.size() > 0) {
                    Iterator paramKeys = params.keySet().iterator();
                    StringBuffer getUrl = new StringBuffer(url.trim());
                    if(url.trim().indexOf("?") > -1) {
                        if(url.trim().indexOf("?") < url.trim().length()-1 &&
                                url.trim().indexOf("&")  < url.trim().length()-1) {
                            getUrl.append("&");
                        }
                    } else {
                        getUrl.append("?");
                    }
                    while(paramKeys.hasNext()) {
                        String key = (String)paramKeys.next();
                        Object value = params.get(key);
                        if(value != null && value instanceof String && !value.equals("")) {
                            getUrl.append(key).append("=").append(value).append("&");
                        } else if(value != null && value instanceof String[] &&
                                ((String[])value).length > 0) {
                            for(String v : (String[])value) {
                                getUrl.append(key).append("=").append(v).append("&");
                            }
                        }
                    }
                    if(getUrl.lastIndexOf("&") == getUrl.length()-1) {
                        httpMethod = new GetMethod(getUrl.substring(0, getUrl.length()-1));
                    } else {
                        httpMethod = new GetMethod(getUrl.toString());
                    }
                } else {
                    httpMethod = new GetMethod(url);
                }
            }
            httpClient.executeMethod(httpMethod);
//            result = httpMethod.getResponseBodyAsString();
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    httpMethod.getResponseBodyAsStream(),"ISO-8859-1"));
            String line = null;
            String html = null;
            while((line = reader.readLine()) != null){
                if(html == null) {
                    html = "";
                } else {
                    html += "\r\n";
                }
                html += line;
            }
            if(html != null) {
                result = new String(html.getBytes("ISO-8859-1"), charset);
            }
        } catch (Exception e) {
            //打印
            throw e;
        } finally {
            if (httpMethod != null) {
                try {
                    httpMethod.releaseConnection();
                } catch (Exception e) {
                    //打印
                    throw e;
                }
            }
        }

        return result;
    }

    public static MyHttpClient getMyHttpClient() {
        return myHttpClient;
    }

    public static void setMyHttpClient(MyHttpClient myHttpClient) {
        MyHttpClient.myHttpClient = myHttpClient;
    }

    public HttpClient getHttpClient() {
        return httpClient;
    }

    public void setHttpClient(HttpClient httpClient) {
        this.httpClient = httpClient;
    }

    public String getCharset() {
        return charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public int getTimeOut() {
        return timeOut;
    }

    public void setTimeOut(int timeOut) {
        this.timeOut = timeOut;
    }

    public boolean isUseProxy() {
        return useProxy;
    }

    public void setUseProxy(boolean useProxy) {
        this.useProxy = useProxy;
    }

    public String getProxyHost() {
        return proxyHost;
    }

    public void setProxyHost(String proxyHost) {
        this.proxyHost = proxyHost;
    }

    public int getProxyPort() {
        return proxyPort;
    }

    public void setProxyPort(int proxyPort) {
        this.proxyPort = proxyPort;
    }

    public String getProxyUsername() {
        return proxyUsername;
    }

    public void setProxyUsername(String proxyUsername) {
        this.proxyUsername = proxyUsername;
    }

    public String getProxyPassword() {
        return proxyPassword;
    }

    public void setProxyPassword(String proxyPassword) {
        this.proxyPassword = proxyPassword;
    }

    public boolean isInitialized() {
        return initialized;
    }

    public void setInitialized(boolean initialized) {
        this.initialized = initialized;
    }
}
